﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
//
//MainWindow初始化
//
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    gridLayout = new QGridLayout;
    mainWindow = new QStackedWidget();
    pauseWindow = new QWidget;
    widget = new QWidget();
    toolWidget = new QWidget;
    vBoxLayout = new QVBoxLayout;
    hBoxLayout = new QHBoxLayout;
    progressBar = new QProgressBar;
    pause = new QPushButton;
    scoreShow = new QLabel;
    timeReminder = new QLabel;
    curResult = new QLabel;
    timer = new QTimer;
    this->setWindowTitle("连连看");
    this->setFixedSize(960,840);
    this->setStyleSheet("#w{border-image:url(:/new/prefix1/SE_project/background.jpg)}");
    initArray();
    this->setCentralWidget(mainWindow);
    connect(timer,SIGNAL(timeout()),this,SLOT(showCurTime()));
    connect(this,SIGNAL(gameOver()),this,SLOT(restart()));
}

MainWindow::~MainWindow()
{
}
//
//单人模式开局
//
void MainWindow::singleModeStart()
{
    remainingTime = 200;
    timer->start(1000);
    mode = 0;
    player1Pos = randomPos();
    loadImg();
    setWindow();
    setToolWidget();
    setPauseWindow();
    //    bgm->setVolume(20);
    //    bgm->play();
    this->show();
}
//
//多人模式开局
//
void MainWindow::multiModeStart()
{
    remainingTime = 200;
    timer->start(1000);
    mode = 1;
    player1Pos = randomPos();
    //玩家2出现在地图上玩家1的相对位置
    player2Pos = Pos(X+3-player1Pos.x,Y+3-player1Pos.y);
    loadImg();
    setWindow();
    setToolWidget();
    setPauseWindow();
    this->show();
}
//
//数组及部分变量初始化
//
void MainWindow::initArray()
{
    blockNum = X*Y;
    if1s = false;
    ifFlash = false;
    ifShuffle = false;
    firstPos[0] = Pos(-1,-1);
    firstPos[1] = Pos(-1,-1);
    secondPos[0] = Pos(-1,-1);
    secondPos[1] = Pos(-1,-1);
    for(int i = 0; i < 3; i++)
        propPos[i] = Pos(-1,-1);
    memset(map,0,sizeof(map));
    memset(score,0,sizeof(score));
    for(int i = 0; i < X*Y; i++)
    {
        randomMap[i] = i%picNum+1;
    }
    srand(time(0));
    //打乱地图
    std::random_device rd;
    std::mt19937 g(rd());
    shuffle(randomMap, randomMap+X*Y,g);
    int k = 0;
    for(int i = 2; i < X+2; ++i)
        for(int j = 2; j < Y+2; ++j) {
            map[i][j] = randomMap[k++];
        }
}
//
//存储方块路径 加载玩家及道具的图像
//
void MainWindow::loadImg()
{
    player1.load(":/new/prefix1/SE_project/p1.png");
    player2.load(":/new/prefix1/SE_project/p2.png");
    block1<<":/new/prefix1/SE_project/0.png"
         <<":/new/prefix1/SE_project/1-1.png"
        <<":/new/prefix1/SE_project/2-1.png"
       <<":/new/prefix1/SE_project/3-1.png"
      <<":/new/prefix1/SE_project/4-1.png"
     <<":/new/prefix1/SE_project/5-1.png"
    <<":/new/prefix1/SE_project/6-1.png"
    <<":/new/prefix1/SE_project/7-1.png"
    <<":/new/prefix1/SE_project/8-1.png"
    <<":/new/prefix1/SE_project/9-1.png"
    <<":/new/prefix1/SE_project/10-1.png"
    <<":/new/prefix1/SE_project/11-1.png"
    <<":/new/prefix1/SE_project/12-1.png";
    block2<<":/new/prefix1/SE_project/0.png"
         <<":/new/prefix1/SE_project/1-2.png"
        <<":/new/prefix1/SE_project/2-2.png"
       <<":/new/prefix1/SE_project/3-2.png"
      <<":/new/prefix1/SE_project/4-2.png"
     <<":/new/prefix1/SE_project/5-2.png"
    <<":/new/prefix1/SE_project/6-2.png"
    <<":/new/prefix1/SE_project/7-2.png"
    <<":/new/prefix1/SE_project/8-2.png"
    <<":/new/prefix1/SE_project/9-2.png"
    <<":/new/prefix1/SE_project/10-2.png"
    <<":/new/prefix1/SE_project/11-2.png"
    <<":/new/prefix1/SE_project/12-2.png";
    propList<<":/new/prefix1/SE_project/l2r.png"
           <<":/new/prefix1/SE_project/u2d.png"
          <<":/new/prefix1/SE_project/u2l.png"
         <<":/new/prefix1/SE_project/u2r.png"
        <<":/new/prefix1/SE_project/d2l.png"
       <<":/new/prefix1/SE_project/d2r.png"
      <<":/new/prefix1/SE_project/p1_l2r.png"
     <<":/new/prefix1/SE_project/p1_u2d.png"
    <<":/new/prefix1/SE_project/p1_u2l.png"
    <<":/new/prefix1/SE_project/p1_u2r.png"
    <<":/new/prefix1/SE_project/p1_d2l.png"
    <<":/new/prefix1/SE_project/p1_d2r.png"
    <<":/new/prefix1/SE_project/p2_l2r.png"
    <<":/new/prefix1/SE_project/p2_u2d.png"
    <<":/new/prefix1/SE_project/p2_u2l.png"
    <<":/new/prefix1/SE_project/p2_u2r.png"
    <<":/new/prefix1/SE_project/p2_d2l.png"
    <<":/new/prefix1/SE_project/p2_d2r.png";
    for(int i = 0; i < propList.size(); i++){
        pathPic[i].load(propList[i]);
    }
    propPic[0].load(":/new/prefix1/SE_project/+1s.png");
    propPic[1].load(":/new/prefix1/SE_project/flash.png");
    propPic[2].load(":/new/prefix1/SE_project/shuffle.png");
    arrangeImg(block1,block2);

}
//
//创建方块
//
Block *MainWindow::createBlock(const QString &str1, const QString &str2)
{
    QPixmap img1,img2;
    img1.load(str1);
    img2.load(str2);
    Block *block = new Block;
    block->setFixedSize(int(img1.height()/7),int(img1.width()/7));
    block->setBlock(img1,img2);
    block->setIconSize(QSize(img1.height()/7,img1.width()/7));
    return block;
}
//
//根据数组创建地图
//
void MainWindow::arrangeImg(const QStringList &block1, const QStringList &block2)
{
    for(int i = 0; i < X+4; ++i)
        for(int j = 0; j < Y+4; ++j) {
            mapper[i][j] = new QSignalMapper;
            int blockNum = map[i][j];
            if(blockNum < 0){                                                               //道具方块
                blocks[i][j] = createBlock(block1[0], block2[0]);
                blocks[i][j]->setIcon(propPic[-blockNum-1]);
            }
            else blocks[i][j] = createBlock(block1[blockNum], block2[blockNum]);            //普通方块
            gridLayout->addWidget(blocks[i][j], i, j, Qt::AlignCenter);
            //批量处理点击方块的槽函数
            connect(blocks[i][j], SIGNAL(clicked()), mapper[i][j], SLOT(map()));
            mapper[i][j]->setMapping(blocks[i][j], 100*i+j);
            connect(mapper[i][j], SIGNAL(mapped(int)), this, SLOT(playerFlash(int)));
        }
}
//
//主游戏窗口界面布置
//
void MainWindow::setWindow()
{

    curScreen = 0;
    mainWindow->addWidget(widget);
    mainWindow->addWidget(pauseWindow);
    mainWindow->setCurrentWidget(widget);
    hBoxLayout->addSpacing(40);
    hBoxLayout->addWidget(timeReminder, Qt::AlignCenter);
    hBoxLayout->addWidget(progressBar, Qt::AlignCenter);
    hBoxLayout->addWidget(scoreShow, Qt::AlignCenter);
    hBoxLayout->addWidget(curResult, Qt::AlignCenter);
    hBoxLayout->addSpacing(10);
    hBoxLayout->addWidget(pause, Qt::AlignCenter);
    hBoxLayout->addSpacing(40);
    toolWidget->setLayout(hBoxLayout);
    toolWidget->setFixedSize(QSize(960,100));
    vBoxLayout->addWidget(toolWidget, Qt::AlignCenter);
    vBoxLayout->addLayout(gridLayout, Qt::AlignCenter);
    vBoxLayout->addSpacerItem(new QSpacerItem(960,20));
    initPlayerPos();
    widget->setLayout(vBoxLayout);
    widget->setFixedSize(960,840);

}
//
//除地图外的显示工具界面布置
//
void MainWindow::setToolWidget()
{
    progressBar->setStyleSheet("QProgressBar{"
                               "width: 10px;"
                               "margin: 0.5px;"
                               "border:1px solid #E8EDF2;"
                               "border-radius:5px;"
                               "text-align:center;"
                               "color:rgba(0,0,0,0);}");
    progressBar->setRange(0,120);
    timeReminder->setFixedSize(50,80);
    timeReminder->setAlignment(Qt::AlignCenter);
    timeReminder->setStyleSheet("QLabel{"
                                "font-size:20px;"
                                "font:bold;"
                                "color:white;}");
    scoreShow->setFixedSize(100,80);
    QString scoreString = "得分:\n" + QString::number(score[0]);
    if(mode)scoreString += ":" + QString::number(score[1]);
    scoreShow->setText(scoreString);
    scoreShow->setStyleSheet("QLabel{"
                             "font-size:20px;"
                             "font:bold;"
                             "color:white;}");
    scoreShow->setAlignment(Qt::AlignCenter);
    curResult->setText(" ");
    curResult->setFixedSize(60,80);
    curResult->setStyleSheet("QLabel{"
                             "font-size:14px;"
                             "font:bold;"
                             "color:white;}");
    curResult->setAlignment(Qt::AlignCenter);
    pause->setFixedSize(90,90);
    pause->setText("暂停");
    pause->setStyleSheet("QPushButton{"
                         "border-radius:5px;"
                         "color:white;"
                         "font-size:30px;"
                         "border: 1px solid #6593cf;"
                         "background-color:rgba(51,102,255,0.1);}"
                         "QPushButton:hover{background-color:rgba(51,102,255,0.7);}"
                         "QPushButton:pressed{background-color:rgba(51,102,255,0.9);}");

}
//
//暂停窗口的界面布置
//
void MainWindow::setPauseWindow()
{
    pauseShow = new QLabel;
    pauseShow->setText("游戏暂停中");
    pauseShow->setAlignment(Qt::AlignCenter);
    pauseLayout = new QVBoxLayout;
    pauseButton[0] = new QPushButton;
    pauseButton[1] = new QPushButton;
    pauseButton[2] = new QPushButton;
    pauseButton[3] = new QPushButton;
    pauseButton[4] = new QPushButton;
    pauseButton[0]->setText("返回游戏");
    pauseButton[1]->setText("保存游戏");
    pauseButton[2]->setText("载入游戏");
    pauseButton[3]->setText("返回主菜单");
    pauseButton[4]->setText("退出游戏");
    pauseLayout->addSpacing(200);
    pauseLayout->addWidget(pauseShow,1,Qt::AlignCenter);
    pauseLayout->addWidget(pauseButton[0],1,Qt::AlignCenter);
    pauseLayout->addWidget(pauseButton[1],1,Qt::AlignCenter);
    pauseLayout->addWidget(pauseButton[2],1,Qt::AlignCenter);
    pauseLayout->addWidget(pauseButton[3],1,Qt::AlignCenter);
    pauseLayout->addWidget(pauseButton[4],1,Qt::AlignCenter);
    pauseLayout->addSpacing(180);
    pauseWindow->setLayout(pauseLayout);
    for(int i = 0; i < 5; i++)
    {
        pauseButton[i]->setFixedSize(300,70);
        pauseButton[i]->setStyleSheet("QPushButton{"
                                      "background-color: rgb(255, 254, 248);"
                                      "border:2px rgb(237, 241, 255);"
                                      "border-radius:7px;"
                                      "padding:2px 3px;"
                                      "font:bold 25px;"
                                      "color:rgba(0,0,0,100);"
                                      "border-style: outset;}"
                                      "QPushButton:hover{background-color:rgb(229, 241, 251); color: black;}"
                                      "QPushButton:pressed{background-color:rgb(204, 228, 247);border-style: inset;}");
    }
    pauseShow->setFixedSize(QSize(300,100));
    pauseShow->setStyleSheet("QLabel{"
                             "font-size:60px;"
                             "background:transparent;"
                             "color:white;"
                             ""
                             "}");
    connect(pause,SIGNAL(clicked()),this,SLOT(gamePause()));
    connect(pauseButton[0],SIGNAL(clicked()),this,SLOT(gamePause()));
    connect(pauseButton[1],SIGNAL(clicked()),this,SLOT(saveGame()));
    connect(pauseButton[2],SIGNAL(clicked()),this,SLOT(loadGame()));
    connect(pauseButton[3],SIGNAL(clicked()),this,SLOT(returnDlg()));
    connect(pauseButton[4],SIGNAL(clicked()),this,SLOT(quit()));
}
//
//显示当前时间 并根据剩余时间放置道具
//
void MainWindow::showCurTime()
{

    if(!curScreen)
    {
        if(remainingTime)
        {
            remainingTime--;
            timeReminder->setNum(remainingTime);
            progressBar->setValue(remainingTime);
            if(!mode){
                if(!if1s&&score[0] >= 100){
                    placeProp(prop1s);
                    if1s = true;
                }
            }else {
                if(!if1s&&score[0]+score[1] >= 200){
                    placeProp(prop1s);
                    if1s = true;
                }
            }
            switch (remainingTime) {
            case 100:if(!mode && !ifFlash){
                    placeProp(propFlash);
                    ifFlash = true;
                }
                break;
            case 180:if(!ifShuffle){
                    placeProp(propShuffle);
                    ifShuffle = true;
                }
                break;
            }
        }
        //时间耗尽时的处理
        else
        {
            if(mode){
                QMessageBox lose;
                if(score[0] > score[1])lose.setText("Time'up! Player1 win!");
                else if(score[0] < score[1])lose.setText("Time'up! Player2 win!");
                else lose.setText("Time'up! You're tied");
                lose.exec();
            }else {
                QMessageBox lose;
                lose.setText("Time'up! You lose!");
                lose.exec();
            }
            timer->stop();
            emit gameOver();
        }
    }

}
//
//键盘事件处理
//
void MainWindow::keyPressEvent(QKeyEvent *event)
{
    if(!curScreen)
    {
        //按esc可暂停游戏
        switch (event->key()) {
        case Qt::Key_Escape:{
            gamePause();
            break;
        }
            //WASD玩家1移动，4568玩家2移动
        case Qt::Key_W:{
            //若玩家在地图边界 不移动
            if(player1Pos.x == 0)break;
            //双人模式下玩家1和玩家2无法互相通过
            if(mode&&(player2Pos.x == player1Pos.x-1) && (player2Pos.y == player1Pos.y))break;
            //在方块四周时通过移动激活方块
            if(map[player1Pos.x-1][player1Pos.y] > 0)
                activeBlock(player1Pos.x-1,player1Pos.y,false);
            //若前进方向为空地则移动角色
            else if(player1Pos.x){
                player1Pos.x--;
                curResult->setText(" ");
                flushPlayerPos();
                if(map[player1Pos.x][player1Pos.y] < 0)handleProp(map[player1Pos.x][player1Pos.y]);
            }
            break;
        }
        case Qt::Key_A:{
            if(player1Pos.y == 0)break;
            if(mode&&(player2Pos.y == player1Pos.y-1) && (player2Pos.x == player1Pos.x))break;
            if(map[player1Pos.x][player1Pos.y-1] > 0)
                activeBlock(player1Pos.x,player1Pos.y-1,false);
            else if(player1Pos.y){
                player1Pos.y--;
                curResult->setText(" ");
                flushPlayerPos();
                if(map[player1Pos.x][player1Pos.y] < 0)handleProp(map[player1Pos.x][player1Pos.y]);
            }
            break;
        }
        case Qt::Key_S:{
            if(player1Pos.x == X+3)break;
            if(mode&&(player2Pos.x == player1Pos.x+1)&&(player2Pos.y == player1Pos.y))break;
            if(map[player1Pos.x+1][player1Pos.y] > 0)
                activeBlock(player1Pos.x+1,player1Pos.y,false);
            else if(player1Pos.x != X+3){
                player1Pos.x++;
                curResult->setText(" ");
                flushPlayerPos();
                if(map[player1Pos.x][player1Pos.y] < 0)handleProp(map[player1Pos.x][player1Pos.y]);
            }
            break;
        }
        case Qt::Key_D:{
            if(player1Pos.y == Y+3)break;
            if(mode&&(player2Pos.x == player1Pos.x)&&(player2Pos.y == player1Pos.y+1))break;
            if(map[player1Pos.x][player1Pos.y+1] > 0)
                activeBlock(player1Pos.x,player1Pos.y+1,false);
            else if(player1Pos.y != Y+3){
                player1Pos.y++;
                curResult->setText(" ");
                flushPlayerPos();
                if(map[player1Pos.x][player1Pos.y] < 0)handleProp(map[player1Pos.x][player1Pos.y]);
            }
            break;
        }
        }
        if(mode){
            switch (event->key()) {
            case Qt::Key_8:{
                if(player2Pos.x == 0)break;
                if((player2Pos.x-1 == player1Pos.x)&&(player2Pos.y == player1Pos.y))break;
                if(map[player2Pos.x-1][player2Pos.y] > 0)
                    activeBlock(player2Pos.x-1,player2Pos.y,true);
                else if(player2Pos.x){
                    player2Pos.x--;
                    curResult->setText(" ");
                    flushPlayerPos();
                    if(map[player2Pos.x][player2Pos.y] < 0)handleProp(map[player2Pos.x][player2Pos.y]);
                }
                break;
            }
            case Qt::Key_4:{
                if(player2Pos.y == 0)break;
                if((player2Pos.x == player1Pos.x)&&(player2Pos.y-1 == player1Pos.y))break;
                if(map[player2Pos.x][player2Pos.y-1] > 0)
                    activeBlock(player2Pos.x,player2Pos.y-1,true);
                else if(player2Pos.y){
                    player2Pos.y--;
                    curResult->setText(" ");
                    flushPlayerPos();
                    if(map[player2Pos.x][player2Pos.y] < 0)handleProp(map[player2Pos.x][player2Pos.y]);
                }
                break;
            }
            case Qt::Key_5:{
                if(player2Pos.x == X+3)break;
                if((player2Pos.x+1 == player1Pos.x)&&(player2Pos.y == player1Pos.y))break;
                if(map[player2Pos.x+1][player2Pos.y] > 0)
                    activeBlock(player2Pos.x+1,player2Pos.y,true);
                else if(player2Pos.x != X+3){
                    player2Pos.x++;
                    curResult->setText(" ");
                    flushPlayerPos();
                    if(map[player2Pos.x][player2Pos.y] < 0)handleProp(map[player2Pos.x][player2Pos.y]);
                }
                break;
            }
            case Qt::Key_6:{
                if(player2Pos.y == Y+3)break;
                if((player2Pos.x == player1Pos.x)&&(player2Pos.y+1 == player1Pos.y))break;
                if(map[player2Pos.x][player2Pos.y+1] > 0)
                    activeBlock(player2Pos.x,player2Pos.y+1,true);
                else if(player2Pos.y != Y+3){
                    player2Pos.y++;
                    curResult->setText(" ");
                    flushPlayerPos();
                    if(map[player2Pos.x][player2Pos.y] < 0)handleProp(map[player2Pos.x][player2Pos.y]);
                }
                break;
            }
            }
        }
    }else{
        //在暂停界面可通过按esc键返回游戏
        switch (event->key()) {
        case Qt::Key_Escape:{
            gamePause();
            break;
        }
        }
    }

}
//
//游戏暂停信号的响应
//
void MainWindow::gamePause()
{
    if(!curScreen)
    {
        mainWindow->setCurrentWidget(pauseWindow);
        curScreen = 1;
    }else{
        mainWindow->setCurrentWidget(widget);
        curScreen = 0;
    }
}
//
//将游戏关键数据写入文本文件中
//
void MainWindow::saveGame()
{
    QMessageBox tmp;
    tmp.setText("已保存");
    tmp.exec();
    ofstream out("C:\\SCHOOL\\homework\\SEP\\gamefile.txt",ios::out);
    out << mode <<" "
        << remainingTime << " "
        << if1s << " "
        << ifFlash << " "
        << ifShuffle << " "
        << player1Pos.x << " "
        << player1Pos.y << " "
        << score[0] <<" "
        << propPos[0].x << " "
        << propPos[0].y << " "
        << propPos[2].x << " "
        << propPos[2].y << " ";
    if (!mode)out << propPos[1].x << " " <<propPos[1].y<<" ";
    out << endl;
    if (mode)
        out << player2Pos.x << " "
            << player2Pos.y << " "
            << score[1] <<endl;
    for(int i = 0; i < X+4; ++i)
        for(int j = 0; j < Y+4; ++j)
            out << map[i][j] << " ";

    out.close();

}
//
//读取游戏
//
void MainWindow::loadGame()
{
    //若当前存档为空 则不读取
    ifstream check("C:\\SCHOOL\\homework\\SEP\\gamefile.txt", ios::in);
    int ch;
    ch = check.get();
    if(check.eof()||ch == EOF){
        check.close();
        QMessageBox tmp;
        tmp.setText("无存档！");
        tmp.exec();
        emit loadFileFail();
        return;
    }
    //当前存档不空，读取游戏关键数据并开始游戏
    ifstream in("C:\\SCHOOL\\homework\\SEP\\gamefile.txt", ios::in);
    in      >> mode
            >> remainingTime
            >> if1s
            >> ifFlash
            >> ifShuffle
            >> player1Pos.x
            >> player1Pos.y
            >> score[0]
            >> propPos[0].x
            >> propPos[0].y
            >> propPos[2].x
            >> propPos[2].y;
    if (!mode)in >> propPos[1].x >> propPos[1].y;
    if (mode){
        in >> player2Pos.x
                >> player2Pos.y
                >> score[1];
    }
    for(int i = 0; i < X+4;++i)
        for(int j = 0; j < Y+4; ++j)
            in >> map[i][j];

    in.close();

    timer->start(1000);
    loadImg();
    setWindow();
    setToolWidget();
    setPauseWindow();
    this->show();
}
//
//退出游戏
//
void MainWindow::quit()
{
    emit quitGame();
}
//
//返回主菜单
//
void MainWindow::returnDlg()
{
    this->hide();
    emit returnLogindlg();
}
//
//选取空地上的随机位置
//
MainWindow::Pos MainWindow::randomPos()
{
    int random = rand()%((X+4)*(Y+4)-blockNum)+1;
    for(int i = 0; i < X+4; i++)
        for(int j = 0; j < Y+4; j++){
            if(map[i][j] == 0)random--;
            if(random == 0)return Pos(i,j);
        }
    return Pos(0,0);
}
//
//在地图最外圈随机位置放置道具
//
MainWindow::Pos MainWindow::randomPropPos()
{
    int random = rand()%(2*X+2*Y-4)+1;
    for(int i = 0; i < X+4; i++)
        for(int j = 0;j < Y+4;j++){
            if(map[i][j] == 0&&(i == 0||i == X+3||j == 0||j == Y+3))random--;
            if(random == 0)return Pos(i,j);
        }
    return Pos(0,0);
}
//
//根据初始玩家位置设置玩家图片
//
void MainWindow::initPlayerPos()
{
    blocks[player1Pos.x][player1Pos.y]->setPlayer(player1);
    if(mode)blocks[player2Pos.x][player2Pos.y]->setPlayer(player2);
}
//
//根据当前玩家位置在地图上刷新玩家图片
//
void MainWindow::flushPlayerPos()
{
    for(int i = 0; i < X+4; i++)
        for(int j=0; j < Y+4; j++)
            if(map[i][j] == 0)blocks[i][j]->clearBlock();
    blocks[player1Pos.x][player1Pos.y]->setPlayer(player1);
    if(mode)blocks[player2Pos.x][player2Pos.y]->setPlayer(player2);
}
//
//方块激活/去激活功能，通过参数plr判断为玩家1或玩家2
//
void MainWindow::activeBlock(int x,int y,bool plr)
{
    //若选中方块为空地，返回
    if(!map[x][y])return;
    //不同玩家对方块的访问记录，判断为第一次或第二次选中方块
    static bool visited[2] = {false,false};
    if(!visited[plr]){
        visited[plr] = !visited[plr];
        blocks[x][y]->changeState();
        firstPos[plr] = Pos(x,y);
    }else {
        visited[plr] = !visited[plr];
        secondPos[plr] = Pos(x,y);
        //若两次选中同一方块 去激活
        if(x == firstPos[plr].x && y == firstPos[plr].y)blocks[x][y]->changeState();
        //若选中不同方块 检查是否可消除
        else if(checkRemovable(plr,true)){
            int blockScore = map[x][y];
            map[firstPos[plr].x][firstPos[plr].y] = 0;
            map[x][y] = 0;
            if(firstPos[!plr] == Pos(x,y) && visited[!plr]){
                visited[!plr] = false;
                blocks[x][y]->changeState();
            }
            curResult->setText("可消除");
            blockNum -= 2;
            blocks[x][y]->changeState();
            score[plr] += 2*blockScore;
            QString scoreString = "得分:\n" + QString::number(score[0]);
            if(mode)scoreString += ":" + QString::number(score[1]);
            scoreShow->setText(scoreString);
            ifGameOver();
        }else {
            blocks[firstPos[plr].x][firstPos[plr].y]->changeState();
            curResult->setText("不可消除");
        }
    }
}
//
//游戏结束时的消息提醒及处理
//
void MainWindow::ifGameOver()
{
    if(!mode){
        //若方块全部消除 游戏结束
        if(blockNum == 0){
            QMessageBox win;
            win.setText("You win!");
            win.exec();
            emit gameOver();
            timer->stop();
        }else if(ifFrozen()){
            //若当前地图无解 游戏结束
            QMessageBox lose;
            lose.setText("No solution! You lose!");
            lose.exec();
            emit gameOver();
            timer->stop();
        }

    }
    if(mode){
        if(blockNum == 0){
            QMessageBox win;
            if(score[0] > score[1])win.setText("Player1 win!");
            else if(score[0] < score[1])win.setText("Player2 win!");
            else win.setText("You're tied");
            win.exec();
            emit gameOver();
            timer->stop();
        }else if(ifFrozen()){
            QMessageBox lose;
            if(score[0] > score[1])lose.setText("No solution! Player1 win!");
            else if(score[0] < score[1])lose.setText("No solution! Player2 win!");
            else lose.setText("No solution! You're tied");
            lose.exec();
            emit gameOver();
            timer->stop();
        }
    }

}
//
//玩家接触到道具的响应事件
//
void MainWindow::handleProp(int num)
{
    num *= -1;
    map[propPos[num-1].x][propPos[num-1].y] = 0;
    switch (num) {
    case prop1s:{
        remainingTime += 30;
        if(remainingTime > 200)remainingTime = 200;
        break;
    }
    case propFlash:{
        flashPermission = 1;
        flashStart = remainingTime;
        break;
    }
    case propShuffle:{
        //打乱道具时将玩家的方块访问清空
        if(firstPos[0].x != -1)activeBlock(firstPos[0].x,firstPos[0].y,false);
        if(firstPos[1].x != -1 && mode)activeBlock(firstPos[1].x,firstPos[1].y,true);
        shuffleBlocks();
        break;
    }
    }
}
//
//根据道具种类放置道具
//
void MainWindow::placeProp(int num)
{
    Pos ppos = randomPropPos();
    //避免道具与玩家、其他道具重合
    while(ppos == player1Pos || ppos == player2Pos || map[ppos.x][ppos.y] < 0)ppos = randomPropPos();
    propPos[num-1] = ppos;
    map[ppos.x][ppos.y] = -1 * num;
    blocks[ppos.x][ppos.y]->setIcon(propPic[num-1]);
}
//
//检查两方块是否有解，并根据参数决定是否画线
//
bool MainWindow::checkRemovable(int num,bool draw)
{
    if(map[firstPos[num].x][firstPos[num].y] != map[secondPos[num].x][secondPos[num].y])return false;
    int x1 = firstPos[num].x;
    int x2 = secondPos[num].x;
    int y1 = firstPos[num].y;
    int y2 = secondPos[num].y;
    return (canLinkDirectly(x1,y1,x2,y2,draw) || canLinkWithOneCorner(x1,y1,x2,y2,draw) || canLinkWithTwoCorner(x1,y1,x2,y2,draw));
}
//
//检查两方块是否可以直线连接
//
bool MainWindow::canLinkDirectly(int x1, int y1, int x2, int y2, bool draw)
{
    bool tmp = true;
    if(x1 != x2 && y1 != y2)return false;
    //水平方向
    if(x1 == x2)
    {
        if(y1 > y2)std::swap(y1,y2);
        for(int i = y1 + 1; i < y2; i++)
            if(map[x1][i])tmp = false;
        if(tmp && draw){
            for(int i = y1 + 1; i < y2; i++){
                if(player1Pos == Pos(x1,i))blocks[x1][i]->setPlayer(pathPic[6]);
                else if(player2Pos == Pos(x1,i))blocks[x1][i]->setPlayer(pathPic[12]);
                else blocks[x1][i]->setPlayer(pathPic[0]);
            }
        }
    }
    //垂直方向
    if(y1 == y2){
        if(x1 > x2)std::swap(x1,x2);
        for(int j = x1 + 1; j < x2; j++)
            if(map[j][y1])tmp = false;
        if(tmp && draw){
            for(int j = x1 + 1; j < x2; j++)
                if(player1Pos == Pos(j,y1))blocks[j][y1]->setPlayer(pathPic[7]);
                else if(player2Pos == Pos(j,y1))blocks[j][y1]->setPlayer(pathPic[13]);
                else blocks[j][y1]->setPlayer(pathPic[1]);
        }
    }
    return tmp;

}
//
//检查两方块是否可通过两段折线连接
//
bool MainWindow::canLinkWithOneCorner(int x1, int y1, int x2, int y2, bool draw)
{
    if(map[x2][y1] == 0){
        if(canLinkDirectly(x1,y1,x2,y1,false)&&canLinkDirectly(x2,y1,x2,y2,false)){
            if(x1 > x2 && y1 > y2 && draw){if(player1Pos == Pos(x2,y1))blocks[x2][y1]->setPlayer(pathPic[10]);
                else if(player2Pos == Pos(x2,y1))blocks[x2][y1]->setPlayer(pathPic[16]);
                else blocks[x2][y1]->setPlayer(pathPic[4]);}
            if(x1 < x2 && y1 < y2 && draw){if(player1Pos == Pos(x2,y1))blocks[x2][y1]->setPlayer(pathPic[9]);
                else if(player2Pos == Pos(x2,y1))blocks[x2][y1]->setPlayer(pathPic[15]);
                else blocks[x2][y1]->setPlayer(pathPic[3]);}
            if(x1 > x2 && y1 < y2 && draw){if(player1Pos == Pos(x2,y1))blocks[x2][y1]->setPlayer(pathPic[11]);
                else if(player2Pos == Pos(x2,y1))blocks[x2][y1]->setPlayer(pathPic[17]);
                else blocks[x2][y1]->setPlayer(pathPic[5]);}
            if(x1 < x2 && y1 > y2 && draw){if(player1Pos == Pos(x2,y1))blocks[x2][y1]->setPlayer(pathPic[8]);
                else if(player2Pos == Pos(x2,y1))blocks[x2][y1]->setPlayer(pathPic[14]);
                else blocks[x2][y1]->setPlayer(pathPic[2]);}
            return (canLinkDirectly(x1,y1,x2,y1,draw)&&canLinkDirectly(x2,y1,x2,y2,draw));
        }
    }
    if(map[x1][y2] == 0){
        if(canLinkDirectly(x1,y1,x1,y2,false)&&canLinkDirectly(x1,y2,x2,y2,false)){
            if(x1 > x2 && y1 > y2 && draw){if(player1Pos == Pos(x1,y2))blocks[x1][y2]->setPlayer(pathPic[9]);
                else if(player2Pos == Pos(x1,y2))blocks[x1][y2]->setPlayer(pathPic[15]);
                else blocks[x1][y2]->setPlayer(pathPic[3]);}
            if(x1 < x2 && y1 < y2 && draw){if(player1Pos == Pos(x1,y2))blocks[x1][y2]->setPlayer(pathPic[10]);
                else if(player2Pos == Pos(x1,y2))blocks[x1][y2]->setPlayer(pathPic[16]);
                else blocks[x1][y2]->setPlayer(pathPic[4]);}
            if(x1 > x2 && y1 < y2 && draw){if(player1Pos == Pos(x1,y2))blocks[x1][y2]->setPlayer(pathPic[8]);
                else if(player2Pos == Pos(x1,y2))blocks[x1][y2]->setPlayer(pathPic[14]);
                else blocks[x1][y2]->setPlayer(pathPic[2]);}
            if(x1 < x2 && y1 > y2 && draw){if(player1Pos == Pos(x1,y2))blocks[x1][y2]->setPlayer(pathPic[11]);
                else if(player2Pos == Pos(x1,y2))blocks[x1][y2]->setPlayer(pathPic[17]);
                else blocks[x1][y2]->setPlayer(pathPic[5]);}
            return (canLinkDirectly(x1,y1,x1,y2,draw)&&canLinkDirectly(x1,y2,x2,y2,draw));
        }
    }
    return false;
}
//
//检查两方块是否可通过三段折线连接
//
bool MainWindow::canLinkWithTwoCorner(int x1, int y1, int x2, int y2, bool draw)
{
    int bestPath = 100, pathLength;
    bool canRemove = false;
    int tmp1x,tmp2x,tmp1y,tmp2y;
    for(int i = 1; i < Y+3; i++){
        if(i != y1 && i != y2){
            if(map[x1][i] == 0 && canLinkDirectly(x1,y1,x1,i,false) && canLinkDirectly(x2,y2,x2,i,false) && canLinkDirectly(x2,i,x1,i,false)){
                canRemove = true;
                //寻找最短路径
                if(draw){pathLength = abs(x2-x1)+abs(i-y1)+abs(i-y2)-1;
                    if(pathLength < bestPath){
                        bestPath = pathLength;
                        tmp1x = x1;
                        tmp2x = x2;
                        tmp1y = i;
                        tmp2y = i;
                    }
                }else return canRemove;
            }
        }
    }
    for(int j = 1; j < X+3; j++){
        if(j != x1 && j != x2){
            if(map[j][y1]==0 && canLinkDirectly(x1,y1,j,y1,false) && canLinkDirectly(x2,y2,j,y2,false) && canLinkDirectly(j,y2,j,y1,false)){
                canRemove = true;
                if(draw){pathLength = abs(y2-y1)+abs(j-x1)+abs(j-x2)-1;
                    if(pathLength < bestPath){
                        bestPath = pathLength;
                        tmp1x = j;
                        tmp2x = j;
                        tmp1y = y1;
                        tmp2y = y2;
                    }
                }else return canRemove;
            }
        }
    }
    if(canRemove){
        if(tmp1x == x1){
            if(tmp1y > y1 && tmp2y > y2 && x1 < x2){
                if(player1Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[10]);
                else if(player2Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[16]);
                else blocks[tmp1x][tmp1y]->setPlayer(pathPic[4]);
                if(player1Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[8]);
                else if(player2Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[14]);
                else blocks[tmp2x][tmp2y]->setPlayer(pathPic[2]);
            }
            if(tmp1y > y1 && tmp2y < y2 && x1 < x2){
                if(player1Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[10]);
                else if(player2Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[16]);
                else blocks[tmp1x][tmp1y]->setPlayer(pathPic[4]);
                if(player1Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[9]);
                else if(player2Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[15]);
                else blocks[tmp2x][tmp2y]->setPlayer(pathPic[3]);
            }
            if(tmp1y < y1 && tmp2y < y2 && x1 < x2){
                if(player1Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[11]);
                else if(player2Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[17]);
                else blocks[tmp1x][tmp1y]->setPlayer(pathPic[5]);
                if(player1Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[9]);
                else if(player2Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[15]);
                else blocks[tmp2x][tmp2y]->setPlayer(pathPic[3]);
            }
            if(tmp1y < y1 && tmp2y > y2 && x1 < x2){
                if(player1Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[11]);
                else if(player2Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[17]);
                else blocks[tmp1x][tmp1y]->setPlayer(pathPic[5]);
                if(player1Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[8]);
                else if(player2Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[14]);
                else blocks[tmp2x][tmp2y]->setPlayer(pathPic[2]);
            }
            if(tmp1y > y1 && tmp2y > y2 && x1 > x2){
                if(player1Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[8]);
                else if(player2Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[14]);
                else blocks[tmp1x][tmp1y]->setPlayer(pathPic[2]);
                if(player1Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[10]);
                else if(player2Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[16]);
                else blocks[tmp2x][tmp2y]->setPlayer(pathPic[4]);
            }
            if(tmp1y > y1 && tmp2y < y2 && x1 > x2){
                if(player1Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[8]);
                else if(player2Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[14]);
                else blocks[tmp1x][tmp1y]->setPlayer(pathPic[2]);
                if(player1Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[11]);
                else if(player2Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[17]);
                else blocks[tmp2x][tmp2y]->setPlayer(pathPic[5]);
            }
            if(tmp1y < y1 && tmp2y < y2 && x1 > x2){
                if(player1Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[9]);
                else if(player2Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[15]);
                else blocks[tmp1x][tmp1y]->setPlayer(pathPic[3]);
                if(player1Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[11]);
                else if(player2Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[17]);
                else blocks[tmp2x][tmp2y]->setPlayer(pathPic[5]);
            }
            if(tmp1y < y1 && tmp2y > y2 && x1 > x2){
                if(player1Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[9]);
                else if(player2Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[15]);
                else blocks[tmp1x][tmp1y]->setPlayer(pathPic[3]);
                if(player1Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[10]);
                else if(player2Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[16]);
                else blocks[tmp2x][tmp2y]->setPlayer(pathPic[4]);
            }

        }
        if(tmp1y == y1){
            if(tmp1x > x1&&tmp2x > x2&&y1 < y2){
                if(player1Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[9]);
                else if(player2Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[15]);
                else blocks[tmp1x][tmp1y]->setPlayer(pathPic[3]);
                if(player1Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[8]);
                else if(player2Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[14]);
                else blocks[tmp2x][tmp2y]->setPlayer(pathPic[2]);
            }
            if(tmp1x < x1&&tmp2x > x2&&y1 < y2){
                if(player1Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[11]);
                else if(player2Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[17]);
                else blocks[tmp1x][tmp1y]->setPlayer(pathPic[5]);
                if(player1Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[8]);
                else if(player2Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[14]);
                else blocks[tmp2x][tmp2y]->setPlayer(pathPic[2]);
            }
            if(tmp1x > x1&&tmp2x < x2&&y1 < y2){
                if(player1Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[9]);
                else if(player2Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[15]);
                else blocks[tmp1x][tmp1y]->setPlayer(pathPic[3]);
                if(player1Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[10]);
                else if(player2Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[14]);
                else blocks[tmp2x][tmp2y]->setPlayer(pathPic[4]);
            }
            if(tmp1x < x1&&tmp2x < x2&&y1 < y2){
                if(player1Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[11]);
                else if(player2Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[17]);
                else blocks[tmp1x][tmp1y]->setPlayer(pathPic[5]);
                if(player1Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[10]);
                else if(player2Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[16]);
                else blocks[tmp2x][tmp2y]->setPlayer(pathPic[4]);
            }
            if(tmp1x > x1&&tmp2x > x2&&y1 > y2){
                if(player1Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[8]);
                else if(player2Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[14]);
                else blocks[tmp1x][tmp1y]->setPlayer(pathPic[2]);
                if(player1Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[9]);
                else if(player2Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[15]);
                else blocks[tmp2x][tmp2y]->setPlayer(pathPic[3]);
            }
            if(tmp1x < x1&&tmp2x > x2&&y1 > y2){
                if(player1Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[10]);
                else if(player2Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[16]);
                else blocks[tmp1x][tmp1y]->setPlayer(pathPic[4]);
                if(player1Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[9]);
                else if(player2Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[15]);
                else blocks[tmp2x][tmp2y]->setPlayer(pathPic[3]);
            }
            if(tmp1x > x1&&tmp2x < x2&&y1 > y2){
                if(player1Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[8]);
                else if(player2Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[14]);
                else blocks[tmp1x][tmp1y]->setPlayer(pathPic[2]);
                if(player1Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[11]);
                else if(player2Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[17]);
                else blocks[tmp2x][tmp2y]->setPlayer(pathPic[5]);
            }
            if(tmp1x < x1&&tmp2x < x2&&y1 > y2){
                if(player1Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[10]);
                else if(player2Pos == Pos(tmp1x,tmp1y))blocks[tmp1x][tmp1y]->setPlayer(pathPic[16]);
                else blocks[tmp1x][tmp1y]->setPlayer(pathPic[4]);
                if(player1Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[11]);
                else if(player2Pos == Pos(tmp2x,tmp2y))blocks[tmp2x][tmp2y]->setPlayer(pathPic[17]);
                else blocks[tmp2x][tmp2y]->setPlayer(pathPic[5]);
            }
        }
        return canLinkDirectly(x1,y1,tmp1x,tmp1y,true)&&canLinkDirectly(tmp1x,tmp1y,tmp2x,tmp2y,true)&&canLinkDirectly(tmp2x,tmp2y,x2,y2,true);
    }else return false;
}
//
//重新启动程序
//
void MainWindow::restart(){
    qApp->quit();
    QProcess::startDetached(qApp->applicationFilePath(), QStringList());
}
//
//道具重排
//
void MainWindow::shuffleBlocks(){
    int tmp1;
    QPixmap img1,img2;
    stack <Pos>tmp2;
    stack <int>tmp3;
    //记录剩余方块的位置及相应的map值
    for(int i = 2; i < X+2;i++)
        for(int j = 2; j < Y+2;j++){
            if(map[i][j]>0){
                tmp2.push(Pos(i,j));
                tmp3.push(map[i][j]);
            }
        }
    tmp1 = tmp2.size();
    //将提取的剩余方块的值构造成数组
    int *tmp4 = new int[tmp1];
    for(int i = 0; i < tmp1; i++){
        tmp4[i] = tmp3.top();
        tmp3.pop();
    }
    //打乱数组
    std::random_device rd;
    std::mt19937 g(rd());
    shuffle(tmp4,tmp4+tmp1,g);
    //剩余方块重新赋值
    for(int i = 0; i < tmp1; i++){
        map[tmp2.top().x][tmp2.top().y] = tmp4[i];
        img1.load(block1[tmp4[i]]);
        img2.load(block2[tmp4[i]]);
        blocks[tmp2.top().x][tmp2.top().y]->setBlock(img1,img2);
        tmp2.pop();
    }
    delete [] tmp4;
}
//
//道具闪现
//
void MainWindow::playerFlash(int buttonPos)
{
    //通过signalmapper传递鼠标点击方块的位置(x,y)
    int x = buttonPos/100;
    int y = buttonPos/100;
    //闪现持续时长5s
    if (flashStart-remainingTime>5)flashPermission = false;
    //移动、激活功能
    if(flashPermission){
        if(map[x][y] == 0){
            player1Pos = Pos(x,y);
            flushPlayerPos();
        }else if(map[x][y] < 0){
            player1Pos = Pos(x,y);
            handleProp(map[x][y]);
            flushPlayerPos();
        }else {
            if (map[x - 1][y] == 0) {
                player1Pos = Pos(x - 1, y);
                activeBlock(x,y,false);
                flushPlayerPos();
                return;
            }
            if (map[x + 1][y] == 0) {
                player1Pos = Pos(x + 1, y);
                activeBlock(x,y,false);
                flushPlayerPos();
                return;
            }
            if (map[x][y - 1] == 0) {
                player1Pos = Pos(x, y - 1);
                activeBlock(x,y,false);
                flushPlayerPos();
                return;
            }
            if (map[x][y + 1] == 0) {
                player1Pos = Pos(x, y + 1);
                activeBlock(x,y,false);
                flushPlayerPos();
                return;
            }
        }
    }else return;
}
//
//判断剩余方块是否有解
//
bool MainWindow::ifFrozen()
{
    checkFrozen.clear();
    //边缘方块进队列
    for(int i = 2; i < X+2; i++)
        for(int j = 2; j < Y+2; j++)
            if(ifAtEdge(i,j))checkFrozen.push_back(Pos(i,j));
    //队列内方块两两检查是否可消除
    while(!checkFrozen.empty()){
        firstPos[2] = checkFrozen.front();
        checkFrozen.pop_front();
        for(int i = 0; i < checkFrozen.size(); i++){
            secondPos[2] = checkFrozen[i];
            if(checkRemovable(2,false))return false;
        }
    }
    return true;
}
//
//判断方块(x,y)是否位于边缘(玩家可接触)
//
bool MainWindow::ifAtEdge(int x, int y)
{
    return map[x][y]>0&&(map[x-1][y] == 0 || map[x+1][y] == 0 || map[x][y-1] || map[x][y+1]);
}
